// copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
// see COPYRIGHT for reuse legalities
//

#import "RIBPointsGeneralPolygons.h"

@implementation RIBPointsGeneralPolygons

+ initialize { return [RIBPointsGeneralPolygons setVersion:1], self; }

- (BOOL)hasBoundingBox { return YES; }

- init
{
  [super init];

  nPolys = 0;
  nLoops = NULL;
  nVertices = NULL;
  vertices = NULL;
  nPolysBuf = (char *)malloc(128);
  cntBuf = (char *)malloc(128);
  
  return self;
}

- free
{
  //if (nLoops) {  free(nLoops); }
  //if (nVertices) { free(nVertices); }
  //if (vertices) { free(vertices); }
  return [super free];
}

- copyFromZone:(NXZone *)zone
{
   id   newCopy = [super copyFromZone:zone];

  NXLogError("WARNING: copyFromZone: incompletely implemented for %s : I'm leaking memory in -free", [[self class] name]);

  return newCopy;
}

- setNPolys:(RtInt)newNPolys nLoops:(RtInt *)newNLoops nVertices:(RtInt *)newNVertices vertices:(RtInt *)newVertices 
     n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
     printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
{  
   nPolys = newNPolys;
   nLoops = newNLoops;
   nVertices = newNVertices;
   vertices = newVertices;
   [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
   nPolysBuf = (char *)malloc(128);
   nVerticesLengthBuf = (char *)malloc(128);
   cntBuf = (char *)malloc(128);

   dirtyBoundingBox = TRUE;
   return self;
}

- setNPolys:(RtInt)newNPolys { nPolys = newNPolys; dirtyBoundingBox = TRUE; return self; }
- setNLoops:(RtInt *)newNLoops { nLoops = newNLoops; dirtyBoundingBox = TRUE; return self; }
- setNVertices:(RtInt *)newNVertices { nVertices = newNVertices; dirtyBoundingBox = TRUE; return self; }
- setVertices:(RtInt *)newVertices { vertices = newVertices; dirtyBoundingBox = TRUE; return self; }

- (RtInt)nPolys { return nPolys; }
- (RtInt *)nLoops { return nLoops; }
- (RtInt *)nVertices { return nVertices; }
- (RtInt *)vertices { return vertices; }


- (BOOL)theSameAs:otherRIBCommand
{
  int    i,
         nLoopsSum = 0, 
         nVerticesSum = 0;
  RtInt  *otherNLoops, *otherNVertices, *otherVertices;


  if ([self class] != [otherRIBCommand class])
  {  return NO;
  }
  if (nPolys != [otherRIBCommand nPolys])
  {  return NO;
  }

  otherNLoops = [otherRIBCommand nLoops];
  for (i = 0; i < nPolys; i++)
  {  if (nLoops[i] != otherNLoops[i])
     {  return NO;
     }
     nLoopsSum += nLoops[i];
  }
  otherNVertices = [otherRIBCommand nVertices];
  for (i = 0; i < nLoopsSum; i++)
  {  if (nVertices[i] != otherNVertices[i])
     {  return NO;
     }
     nVerticesSum += nVertices[i];
  }

  otherVertices = [otherRIBCommand vertices];
  for (i = 0; i < nVerticesSum; i++)
  {  if (vertices[i] != otherVertices[i])
     {  return NO;
     }
  }

  return [super theSameAs:otherRIBCommand];
}


- (BOOL)similarTo:otherRIBCommand
{
  int    i,
         nLoopsSum = 0, 
         nVerticesSum = 0;
  RtInt  *otherNLoops, *otherNVertices, *otherVertices;


  if ([self class] != [otherRIBCommand class])
  {  return NO;
  }
  if (nPolys != [otherRIBCommand nPolys])
  {  return NO;
  }
  otherNLoops = [otherRIBCommand nLoops];
  for (i = 0; i < nPolys; i++)
  {  if (nLoops[i] != otherNLoops[i])
     {  return NO;
     }
     nLoopsSum += nLoops[i];
  }
  otherNVertices = [otherRIBCommand nVertices];
  for (i = 0; i < nLoopsSum; i++)
  {  if (nVertices[i] != otherNVertices[i])
     {  return NO;
     }
     nVerticesSum += nVertices[i];
  }

  otherVertices = [otherRIBCommand vertices];
  for (i = 0; i < nVerticesSum; i++)
  {  if (vertices[i] != otherVertices[i])
     {  return NO;
     }
  }

  return YES;
}



- renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
{
  RiPointsGeneralPolygonsV(nPolys, nLoops, nVertices, vertices, n, tokens, parms);
  return self;
}

- (BOOL)isMotionBlurrable { return YES; }

- writeEve:(NXStream *)stream atTabLevel:(int)tab
{
   int  i, sum = 0;


   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "PointsGeneralPolygons {");
   for (i = 0; i < nPolys; i++)
   {  NXPrintf(stream, "%d ", nLoops[i]);
   }
   NXPrintf(stream, "} {");
   for (i = 0; i < nPolys; i++)
   {  NXPrintf(stream, "%d ", nVertices[i]);
     sum += nVertices[i];
   }
   NXPrintf(stream, "} {");
   for (i = 0; i < sum; i++)
   {  NXPrintf(stream, "%d ", vertices[i]);
   }
   NXPrintf(stream, "} ");

   [super writeParameterList:stream];
   return self;
}

#define typeVector "l"
#define typeValues &nPolys

- read:(NXTypedStream*)stream 
{
    int version, i, cnt = 0, nVerticesLength = 0;
    
    [super read:stream];
    nPolysBuf = (char *)malloc(128);
    nVerticesLengthBuf = (char *)malloc(128);
    cntBuf = (char *)malloc(128);
    
    version = NXTypedStreamClassVersion(stream,"RIBGeneralPolygon");
    if (version == 0) NXReadTypes(stream,"i",&version), version=1;
    if (version == 1) {
	NXReadTypes(stream,typeVector,typeValues);
	
	nLoops = (long *)NXZoneMalloc([self zone], nPolys*sizeof(long));
	NXReadArray(stream, "l", nPolys, nLoops);
	for (i = 0; i < nPolys; i++) {
	    nVerticesLength += nLoops[i];
	}
	nVertices = (long *)NXZoneMalloc([self zone], nVerticesLength*sizeof(long));
	NXReadArray(stream, "l", nVerticesLength, nVertices);
	for (i = 0; i < nPolys; i++) {
	    cnt += nVertices[i];
	}
	vertices = (long *)NXZoneMalloc([self zone], cnt*sizeof(long));
	NXReadArray(stream, "l", cnt, vertices);
    } 
    return self;
}

- write:(NXTypedStream*)stream 
{
    int   i, cnt = 0, nVerticesLength = 0;
    
    [super write:stream];
    NXWriteTypes(stream, typeVector, typeValues);
    NXWriteArray(stream, "l", nPolys, nLoops);
    for (i = 0; i < nPolys; i++) {
	nVerticesLength += nLoops[i];
    }
    NXWriteArray(stream, "l", nVerticesLength, nVertices);
    for (i = 0; i < nPolys; i++) {
	cnt += nVertices[i];
    }
    NXWriteArray(stream, "l", cnt, vertices);
    return self;
}


@end
